#ifndef SCHEDULER_H_
#define SCHEDULER_H_

#ifndef PIDTYPE
#define PIDTYPE
typedef int pid;
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <vector>
#include <string>

//using namespace std;

typedef struct processDefinition {
	int totalTimeLimit, initialPriority, c1, c2, b1, b2, x0, y0, w;
} processDefinition;

typedef struct processStatistics {
	bool running;
	pid processId;
	int waitingTime;
	double averageResponseTime;
	int turnaroundTime; // is this an int or a double?
	int garanteedSchedulerFraction;
};

typedef enum action {
	STATISTICS = 0,
	UPLOAD_SETUP_FILE = 1,
	CHANGE_POLICY = 2,
	CHANGE_QUANTUM = 3,
	EXIT = 4
} action;	

typedef enum runCommand {
	ASK_FOR_SETUP_FILE = 0,
	READ_SETUP_FILE = 1,
	ASK_FOR_POLICY = 2,
	ASK_FOR_QUANTUM = 3,
	CREATE_PROCESSES = 4,
	RUN_PROCESSES = 5
} runCommand;

class Scheduler {
public:
	Scheduler(int numOfProcesses, processDefinition processDefs[]);
	virtual ~Scheduler();

	pid createProcess(pid schedulerPID, processDefinition pDef, int i);

	//string askForSetupFile();
	//void readSetupFile();
	string askForSchedulingPolicy();
	string askForCPUTimeQuantum();

	string askForInstructions();
	void performInstruction(string action);
	void printStatistics();
	void eraseStatistics();
	void eraseCurrentProcessDefinitions();
	void changePolicy();
	void changeQuntum();
	void run(runCommand command); // 1. ask for setup file... etc like in the document.
	pid chooseNextProcessRR();
	pid chooseNextProcessGS();
	pid chooseNextProcessDMLS();
	pid chooseNextProcessPersonal();

	// TODO look at the assignment PS for help!
	void incrementGlobalClock();
	void suspendRunningProcess();
	void updateStatistics(); // signature will probably change
	void catchSIGUSR1(int num);
	void catchSIGUSR2(int num);
	void exit();
	char* itoa(int value);

	// Fields
private:
	int n;
	vector<processDefinition> procDefs;
	vector<processStatistics> procStatistics;
	vector<pid> readyQueue;
	vector<pid> blockedQueue;
	int globalClock;
};

#endif /*SCHEDULER_H_*/
